package com.qing.springcloud.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.qing.springcloud.common.FriendRequestStatusEnum;
import com.qing.springcloud.common.UserFriendTypeEnum;
import com.qing.springcloud.dao.FriendRequestDao;
import com.qing.springcloud.dao.UserDao;
import com.qing.springcloud.dao.UserFriendDao;
import com.qing.springcloud.dto.friend.FriendRequestDTO;
import com.qing.springcloud.dto.friend.HandleFriendRequestDTO;
import com.qing.springcloud.dto.user.UserDTO;
import com.qing.springcloud.entity.FriendRequest;
import com.qing.springcloud.entity.User;
import com.qing.springcloud.entity.UserFriend;
import com.qing.springcloud.exception.BusinessException;
import com.qing.springcloud.notification.FriendRequestNotification;
import com.qing.springcloud.notification.FriendAddedNotification;
import com.qing.springcloud.notification.FriendDeletedNotification;
import com.qing.springcloud.utils.EnumUtils;
import com.qing.springcloud.utils.RedisUtils;
import com.qing.springcloud.utils.UserInfoUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.qing.springcloud.service.FriendService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 好友关系表服务接口实现
 *
 * @author zhipeng.cao
 * @since 2025-07-09 20:09:50
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class FriendServiceImpl implements FriendService {
    private final FriendRequestDao friendRequestDao;
    private final UserFriendDao userFriendDao;
    private final UserDao userDao;

    private final RabbitTemplate rabbitTemplate;
    private final String exchange="friend-exchange";
    private  final UserInfoUtils userInfoUtils;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendFriendRequest(FriendRequestDTO dto) {
        Long fromUserId = StpUtil.getLoginIdAsLong();
        Long toUserId = dto.getToUserId();
        // 检查是否已是好友
        if (userFriendDao.existsByUserIdAndFriendId(fromUserId, toUserId)) {
            throw new BusinessException("对方已是你的好友");
        }

        // 创建好友请求
        FriendRequest request = new FriendRequest();
        request.setFromUser(fromUserId);
        request.setToUser(toUserId);
        request.setStatus(FriendRequestStatusEnum.WAITING.getCode());
        request.setMessage(dto.getMessage());
        request.setCreatedAt(DateUtil.date());
        request.setUpdatedAt(DateUtil.date());
        friendRequestDao.save(request);

        // 发送通知（通过RabbitMQ）
        FriendRequestNotification notification=new FriendRequestNotification(
                request.getId(),
                fromUserId,
                userDao.getUsername(fromUserId),
                dto.getMessage(),
                DateUtil.current()
        );
        rabbitTemplate.convertAndSend(exchange, "friend-request." + toUserId,notification);
    }

    @Override
    @Transactional
    public void handleFriendRequest(HandleFriendRequestDTO dto) {
        FriendRequest request = friendRequestDao.getById(dto.getRequestId())
                .orElseThrow(() -> new BusinessException("好友请求不存在"));

        if (!request.getToUser().equals(dto.getCurrentUserId())) {
            throw new BusinessException("无权处理此请求");
        }

        request.setStatus(dto.getStatus());
        request.setUpdatedAt(DateUtil.date());
        friendRequestDao.updateById(request);

        if (EnumUtils.equals(FriendRequestStatusEnum.AGREE,dto.getStatus())) {
            // 建立双向好友关系
            Long fromUserId = request.getFromUser();
            Long toUserId = request.getToUser();
            createFriendRelationship(fromUserId,toUserId);
            createFriendRelationship(toUserId,fromUserId);

            // 发送好友建立通知
            rabbitTemplate.convertAndSend(exchange, "friend-added." + fromUserId,new FriendAddedNotification(toUserId));
        }
    }

    private void createFriendRelationship(Long user1, Long user2) {
        UserFriend userFriend = new UserFriend();
        userFriend.setUserId(user1);
        userFriend.setFriendId(user2);
        userFriendDao.save(userFriend);
    }

    @Override
    @Transactional
    public void deleteFriend(Long userId, Long friendId) {
        userFriendDao.deleteByUserIdAndFriendId(userId, friendId);

        // 发送通知
        FriendDeletedNotification notification =new  FriendDeletedNotification(friendId,DateUtil.current());
        rabbitTemplate.convertAndSend(exchange, "friend-deleted." + userId, notification);
    }

    @Override
    public List<UserDTO> getFriendList(Long userId) {
        List<Long> friendIds = userFriendDao.findFriendIdsByUserId(userId,UserFriendTypeEnum.FRIEND.getCode());
        return userDao.findAllById(friendIds).stream()
                .map(this::convertToUserDTO)
                .collect(Collectors.toList());
    }

    @Override
    public void blacklistFriend(Long userId, Long friendId) {
        UserFriend userFriend = userFriendDao.findByUserIdAndFriendId(userId, friendId)
                .orElseThrow(() -> new BusinessException("好友关系不存在"));

        userFriend.setRelationType(UserFriendTypeEnum.BLACKLIST.getCode());
        userFriendDao.updateById(userFriend);
    }

    @Override
    public List<Long> getFriendIds(Long userId) {
        return userFriendDao.findFriendIdsByUserId(userId,UserFriendTypeEnum.FRIEND.getCode());
    }

    private UserDTO convertToUserDTO(User user) {
        // 简化的DTO转换
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(user, userDTO);
        return userDTO;
    }
}